# -*- coding: utf-8 -*-
"""
其他转换器
支持网页转PDF、文档转TXT等
"""

import os
from pathlib import Path
import pdfkit
import docx
import PyPDF2
from docx import Document
import re


class OtherConverter:
    """其他转换器类"""

    def __init__(self):
        pass

    def url_to_pdf(self, url, output_dir):
        """
        网页转PDF
        :param url: 网址
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not url or not url.strip():
            raise ValueError("URL不能为空")

        # 确保URL有协议头
        if not url.startswith(('http://', 'https://')):
            url = 'https://' + url

        # 生成输出文件名（从URL提取）
        try:
            filename = re.sub(r'[^\w\s-]', '_', url.split('//')[-1].split('/')[0])
        except:
            filename = "webpage"

        output_path = os.path.join(output_dir, f"{filename}.pdf")

        # 方法1: 尝试使用 wkhtmltopdf
        wkhtmltopdf_paths = [
            r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe',
            r'C:\Program Files (x86)\wkhtmltopdf\bin\wkhtmltopdf.exe',
            'wkhtmltopdf'  # 如果在PATH中
        ]

        for wk_path in wkhtmltopdf_paths:
            try:
                config = pdfkit.configuration(wkhtmltopdf=wk_path)
                options = {
                    'encoding': 'UTF-8',
                    'page-size': 'A4',
                    'margin-top': '0.75in',
                    'margin-right': '0.75in',
                    'margin-bottom': '0.75in',
                    'margin-left': '0.75in',
                    'enable-local-file-access': None
                }
                pdfkit.from_url(url, output_path, configuration=config, options=options)

                if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                    print("使用wkhtmltopdf转换成功")
                    return output_path
            except Exception as e:
                continue

        # 方法2: 使用 weasyprint
        try:
            from weasyprint import HTML
            HTML(url).write_pdf(output_path)

            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                print("使用weasyprint转换成功")
                return output_path
        except Exception as e:
            print(f"weasyprint转换失败: {str(e)}")

        # 方法3: 使用 selenium + Chrome
        try:
            from selenium import webdriver
            from selenium.webdriver.chrome.options import Options
            from selenium.webdriver.chrome.service import Service
            import time
            import base64

            chrome_options = Options()
            chrome_options.add_argument('--headless')
            chrome_options.add_argument('--disable-gpu')
            chrome_options.add_argument('--no-sandbox')
            chrome_options.add_argument('--disable-dev-shm-usage')

            driver = webdriver.Chrome(options=chrome_options)
            driver.get(url)
            time.sleep(3)  # 等待页面加载

            # 打印为PDF
            print_options = {
                'paperWidth': 8.27,
                'paperHeight': 11.69,
                'marginTop': 0.4,
                'marginBottom': 0.4,
                'marginLeft': 0.4,
                'marginRight': 0.4,
                'printBackground': True
            }

            result = driver.execute_cdp_cmd('Page.printToPDF', print_options)
            with open(output_path, 'wb') as f:
                f.write(base64.b64decode(result['data']))

            driver.quit()

            if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
                print("使用Selenium转换成功")
                return output_path
        except Exception as e:
            print(f"Selenium转换失败: {str(e)}")

        # 如果所有方法都失败
        raise Exception("网页转PDF失败：所有转换方法都失败了。\n建议：\n1. 安装wkhtmltopdf: https://wkhtmltopdf.org/downloads.html\n2. 或安装Chrome浏览器\n3. 检查网址是否可访问\n4. 某些网站可能有反爬虫保护")

    def doc_to_txt(self, doc_path, output_dir):
        """
        任意文档转TXT
        支持 PDF、Word 等格式
        :param doc_path: 文档文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        base_name = os.path.splitext(os.path.basename(doc_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.txt")

        ext = os.path.splitext(doc_path)[1].lower()

        try:
            if ext in ['.docx', '.doc']:
                # Word文档转TXT
                text = self._word_to_text(doc_path)
            elif ext == '.pdf':
                # PDF转TXT
                text = self._pdf_to_text(doc_path)
            elif ext == '.txt':
                # 已经是TXT，直接复制
                with open(doc_path, 'r', encoding='utf-8', errors='ignore') as f:
                    text = f.read()
            else:
                # 尝试直接读取
                with open(doc_path, 'r', encoding='utf-8', errors='ignore') as f:
                    text = f.read()

            # 保存为TXT
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(text)

            return output_path
        except Exception as e:
            raise Exception(f"文档转TXT失败: {str(e)}")

    def _word_to_text(self, word_path):
        """
        从Word文档提取文本
        :param word_path: Word文件路径
        :return: 文本内容
        """
        try:
            # 尝试使用 python-docx
            doc = Document(word_path)
            text = []
            for paragraph in doc.paragraphs:
                text.append(paragraph.text)
            return '\n'.join(text)
        except Exception as e:
            # 如果失败，尝试使用 win32com
            import win32com.client
            import pythoncom

            pythoncom.CoInitialize()
            try:
                word = win32com.client.Dispatch("Word.Application")
                word.Visible = False
                doc = word.Documents.Open(os.path.abspath(word_path))
                text = doc.Content.Text
                doc.Close()
                word.Quit()
                return text
            finally:
                pythoncom.CoUninitialize()

    def _pdf_to_text(self, pdf_path):
        """
        从PDF提取文本
        :param pdf_path: PDF文件路径
        :return: 文本内容
        """
        text = []
        try:
            with open(pdf_path, 'rb') as file:
                pdf_reader = PyPDF2.PdfReader(file)
                for page in pdf_reader.pages:
                    text.append(page.extract_text())
        except Exception as e:
            # 如果 PyPDF2 失败，尝试使用 pdfplumber
            try:
                import pdfplumber
                with pdfplumber.open(pdf_path) as pdf:
                    for page in pdf.pages:
                        text.append(page.extract_text())
            except:
                raise Exception(f"无法从PDF提取文本: {str(e)}")

        return '\n'.join(text)
